package com.wpf.system.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wpf.system.entity.*;
import com.wpf.system.entity.vo.UserInfoVO;
import com.wpf.system.mapper.RoleMapper;
import com.wpf.system.mapper.RoleMenuMapper;
import com.wpf.system.service.*;
import com.wpf.system.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
* @author ferna
* @description 针对表【user(用户信息表)】的数据库操作Service实现
* @createDate 2022-12-15 22:31:16
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Resource
    private DepartmentService departmentService;

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private  AssetService assetService;

    @Value("${system.userDefaultRole}")
    private Long defaultRole;

    @Value("${system.userDefaultDeptId}")
    private Long defaultDeptId;

    @Value("${system.defaultFieldUserManagerMenu}")
    private Long defaultFieldUserManagerMenu;

    @Override
    public IPage<User> getUserExceptLoginUser(int page, int pageSize, Long id, Long deptId, String type, String searchContent) {
        IPage<User> pageCondition = new Page<>(page, pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(User::getId,id);
        queryWrapper.select(User.class,user -> !user.getColumn().equals("password"));
        if(ObjectUtil.isNotNull(deptId)){
            queryWrapper.in(User::getDeptId,departmentService.getDeptIdByPid(deptId));
        }
        if(StrUtil.isNotBlank(type)){
            switch (type){
                case "0" :
                    queryWrapper.like(User::getNid,searchContent);
                    break;
                case "1" :
                    queryWrapper.like(User::getUsername,searchContent);
                    break;
                case "2" :
                    queryWrapper.like(User::getPhone,searchContent);
                    break;
                case "3" :
                    queryWrapper.like(User::getNickname,searchContent);
                    break;
            }
        }
        return this.baseMapper.selectPage(pageCondition,queryWrapper);
    }

    @Override
    public UserInfoVO getUserAllInfo(Long id) {
        User user = this.baseMapper.selectById(id);
        user.setPassword(null);
        Department userDept = departmentService.getOne(new LambdaQueryWrapper<Department>().eq(Department::getId,user.getDeptId()));
        Asset userAsset = assetService.getAssetByUid(id);
        List<UserRole> userRoleList =  userRoleService.getUserRoleByUid(id);
        List<String> roleNameList = new ArrayList<>();
        for(UserRole item : userRoleList){
            Role role = roleMapper.selectById(item.getRid());
            roleNameList.add(role.getRoleName());
        }
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUser(user);
        userInfoVO.setDeptName(userDept.getDeptName());
        userInfoVO.setRoleName(roleNameList);
        userInfoVO.setBalance(userAsset.getBalance());
        userInfoVO.setPoint(userAsset.getPoint());
        return userInfoVO;
    }

    @Override
    public List<User> getFieldUserManager() {
        //查询拥有场馆管理的角色
        QueryWrapper<RoleMenu> roleMenuQueryWrapper = new QueryWrapper<>();
        roleMenuQueryWrapper.lambda().eq(RoleMenu::getMid,defaultFieldUserManagerMenu);
        roleMenuQueryWrapper.lambda().select(RoleMenu::getRid);
        List<RoleMenu> roleMenuList = roleMenuMapper.selectList(roleMenuQueryWrapper);
        if(roleMenuList.size()>0){
            List<Long> ridList =  new ArrayList<>();
            roleMenuList.forEach(item-> ridList.add(item.getRid()));
            //查询拥有对应角色的用户
            QueryWrapper<UserRole> userRoleQueryWrapper= new QueryWrapper<>();
            userRoleQueryWrapper.lambda().in(UserRole::getRid,ridList);
            userRoleQueryWrapper.lambda().select(UserRole::getUid);
            List<UserRole> userRoleList = userRoleService.getBaseMapper().selectList(userRoleQueryWrapper);
            if (userRoleList.size()>0){
                List<Long> uidList =  new ArrayList<>();
                userRoleList.forEach(item-> uidList.add(item.getUid()));
                QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper.lambda().in(User::getId,uidList);
                userQueryWrapper.lambda().select(User::getId,User::getNid,User::getUsername,User::getSex,User::getPhone);
                return this.baseMapper.selectList(userQueryWrapper);
            }
        }
        return null;
    }

    public User getUserByNid(String nid){
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNid,nid);
        return getOne(queryWrapper);
    }

    @Override
    public Boolean addUser(User user) {
        String userNid = user.getNid();
        String userPhone = user.getPhone();
        String userEmail = user.getEmail();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //密码加密
        if(StrUtil.isNotBlank(user.getPassword())){
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }else{
            if(StrUtil.isBlank(userPhone)||StrUtil.isBlank(userEmail)){
                user.setPassword(passwordEncoder.encode(userNid));
                //密码强度设置为 低
                user.setCheckPassword(1);
            }else{
                //首字母大写电子邮箱域名+学号后四位+电话号码4-7位
                String front = userEmail.substring(userEmail.lastIndexOf("@")+1, userEmail.lastIndexOf("."));
                String pwFront = front.substring(0,1).toUpperCase()+front.substring(1);
                String pwMiddle = userNid.substring(userNid.length()-4);
                String pwEnd =  userPhone.substring(3,7);
                String defaultPassword = pwFront+pwMiddle+pwEnd;
                user.setPassword(passwordEncoder.encode(defaultPassword));
                //密码强度设置为 较强
                user.setCheckPassword(3);
            }
        }
        //创建资产密码
        String assetKey;
        if(StrUtil.isNotBlank(userPhone)){
            assetKey = userPhone.substring(3,7) + userNid.substring(userNid.length()-2);
        }else{
            assetKey =  userNid.substring(userNid.length()-6);
        }
        Asset asset = new Asset();
        asset.setAssetKey(passwordEncoder.encode(assetKey));
        if(Convert.toBool(assetService.save(asset))){
            user.setAssetId(asset.getId());
            if(ObjectUtil.isNull(user.getDeptId())){
                user.setDeptId(defaultDeptId);
            }
            if(Convert.toBool(baseMapper.insert(user))){
                //添加基本的角色
                UserRole userRole = new UserRole();
                userRole.setUid(user.getId());
                userRole.setRid(defaultRole);
                userRoleService.save(userRole);
                return true;
            }
        }
        return false;
    }

    @Override
    public int editUserStatusById(Long id) { return this.baseMapper.editUserStatusById(id); }

    @Override
    public int editUserAvatarById(Long id,String avatar) {
        return baseMapper.editUserAvatarById(id,avatar);
    }

    @Override
    @Transactional
    public Boolean deleteUserById(Long id) {
        try{
            //删除相关资产
            User user = baseMapper.selectById(id);
            assetService.removeById(user.getAssetId());
            //删除用户
            if(Convert.toBool(baseMapper.deleteById(id))){
                //关联删除
                userRoleService.deleteUserRoleByUid(id);
                return true;
            }else{
                return false;
            }
        }catch (RuntimeException e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    @Override
    public Boolean editUserPassword(Long id, String password,Integer checkPassword) {
        return this.baseMapper.editUserPassword(id,password,checkPassword);
    }

    @Override
    public Boolean editUserEmailStatus(Long id) {
        return this.baseMapper.editUserEmailStatus(id);
    }
}